#pragma once

#include "IEntity.h"
#include "EntityManager.h"
#include "../EventManager.h"

#include <list>
#include <vector>
#include <map>

/**
 * A tile an ent can move to
 */
struct PathNode
{   
	PathNode(Vector2f dest) { location = dest;};
	PathNode* entityPath;
    Vector2f location;
};



class AI_Brain : public IEventListener
{
public:
	AI_Brain(void);
    // start - put in ai_manager**************

	void controlEntities();
	void addEntity(IEntity* ptr);
	void RemoveEntity( IEntity* ent );
    /* Get the Name of the Listener */
	std::string GetName() { return "AI_Manager"; };
    /** Get Listener Type - Events this listener listens too */
	int GetListenerType() { return LT_ADD_RM_ENTITY; };

    /** Handle an event */
    bool HandleEvent( IEvent* e );

    // - end put in ai_manager********************

	void continuePatrol(IEntity* entPtr);



public:
	virtual ~AI_Brain(void);
private:
	void think(IEntity* entPtr);
	void checkStuck(IEntity* entPtr);
	void walkTo(const Vector2f current, const Vector2f destination, IEntity* entPtr);
	void goToPlayer(IEntity* entPtr);
	void fillPath(IEntity* entPtr, int pixelsAway);
	bool legalMove(IEntity* entPtr);
    void addNeighbor(std::list<PathNode> &openList,std::list<PathNode> &closedList, PathNode &entNode, IEntity* entPtr, const Vector2f &offSet);
	void addNeighbors(std::list<PathNode> &openList,std::list<PathNode> &closedList, PathNode &entNode, IEntity* entPtr);
    bool closeEnough(const Vector2f &dest, IEntity* entPtr);
    bool PlayerInView(int face, const Vector2f &playerLoc, const Vector2f &entLoc);
    /**
        Data needed for ai to make decisions
    */
	struct AI_Data
	{
		std::vector<Vector2f> patrol;
		bool awareOfPlayer;
		std::deque<Vector2f> path; // changed from vector for faster front and back inserts
		Vector2f lastLocation;
		Vector2f patrolVelocity;
		size_t   patrolIndex;
	};

	std::list<IEntity*> entList;
	std::map< IEntity*, AI_Data > m_dataTable;

	
	
};

